<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\common\model\PhotoAddress;
use app\common\model\Product;
use app\common\model\UserAddress;
use app\common\model\UserSchool;
use app\common\model\Order as OrderModel;
use think\addons\Service;
use think\Db;
use think\Exception;
use think\exception\PDOException;

class Order extends Api
{
    protected $noNeedLogin = [''];
    protected $noNeedRight = ['*'];



    /** 创建订单 */
    public function create()
    {
        $param = $this->request->param();
        $this->validateCommon('Order.create', $this->serial_number);
        $productInfo     = Product::where(['id' => $param['productId'], 'status' => 1])
                                  ->field('id,product_name,unit_price,condition,product_main_image,product_style')
                                  ->find();
        $productStyleArr = json_decode($productInfo['product_style'], true);
        $newStyleArr     = [];
        foreach ($productStyleArr as $k => $value) {
            $newStyleArr[] = $k;
        }
        if (!in_array($param['productStyle'], $newStyleArr)) $this->error('商品款式错误', '', 0, $this->serial_number);
        if (!$productInfo) $this->error('商品已下架或不存在,请联系管理员', '', 0, $this->serial_number);
        if ($param['productNum'] < $productInfo['condition']) $this->error('当前购买数量,小于商品设置起拍数量'.'-'.$productInfo['condition']);
        $photoAddressInfo = PhotoAddress::where(['user_id' => $this->auth->id, 'id' => $param['photoAddressId']])->find();
        if (!$photoAddressInfo) $this->error('拍摄地址不存在,请重试', '', 0, $this->serial_number);
        $userSchoolInfo = UserSchool::where(['user_id' => $this->auth->id, 'id' => $param['userSchoolId']])->find();
        if (!$userSchoolInfo) $this->error('学校地址不存在,请重试', '', 0, $this->serial_number);
        $userAddressInfo = UserAddress::where(['user_id' => $this->auth->id, 'id' => $param['userAddressId']])->find();
        if (!$userAddressInfo) $this->error('收货地址不存在,请重试', '', 0, $this->serial_number);
        $product_total_price = bcmul($productInfo['unit_price'], $param['productNum'], 2); //商品总价
        $photoAddressArr     = [
            'name'           => $photoAddressInfo['name'],
            'mobile'         => $photoAddressInfo['mobile'],
            'province'       => $photoAddressInfo['province'],
            'city'           => $photoAddressInfo['city'],
            'county'         => $photoAddressInfo['county'],
            'address_detail' => $photoAddressInfo['address_detail'],
        ];
        $userSchoolArr       = [
            'province'    => $userSchoolInfo['province'],
            'city'        => $userSchoolInfo['city'],
            'county'      => $userSchoolInfo['county'],
            'school_name' => $userSchoolInfo['school_name'],
            'grade'       => $userSchoolInfo['grade'],
            'class'       => $userSchoolInfo['class'],
        ];
        $userAddressArr      = [
            'name'   => $userAddressInfo['name'],
            'mobile' => $userAddressInfo['mobile'],
            'city'   => $userAddressInfo['address'],
            'detail' => $userAddressInfo['address_detail'],
        ];
        $photoAddressJson    = json_encode($photoAddressArr, JSON_UNESCAPED_SLASHES + JSON_UNESCAPED_UNICODE);
        $userSchoolJson      = json_encode($userSchoolArr, JSON_UNESCAPED_SLASHES + JSON_UNESCAPED_UNICODE);
        $addressJson         = json_encode($userAddressArr, JSON_UNESCAPED_SLASHES + JSON_UNESCAPED_UNICODE);
        $orderData           = [
            'user_id'             => $this->auth->id,
            'order_sn'            => makePaySn(rand(1, 9)),
            'product_id'          => $productInfo['id'],
            'product_num'         => $param['productNum'],
            'product_name'        => $productInfo['product_name'],
            'product_style'       => $param['productStyle'],
            'product_image'       => $productInfo['product_main_image'],
            'product_total_price' => $product_total_price,
            'user_address_json'   => $photoAddressJson,
            'address_json'        => $addressJson,
            'user_school_json'    => $userSchoolJson,
            'photo_people_num'    => $param['photoPeopleNum'] ?? "",
            'photo_time'          => $param['photoTime'] ?? "",
            'memo'                => $param['memo'] ?? ""
        ];
        $res                 = OrderModel::create($orderData);
        if ($res) $this->success('下单成功', ['orderSn' => $res->order_sn], 1, $this->serial_number);
        $this->error('下单失败', '', 0, $this->serial_number);
    }

    /**
     * 订单支付
     *
     * @return void
     */

    public function orderPay()
    {
        $orderSn   = $this->request->post('orderSn');
        $payType   = $this->request->post('payType', 'wechat');//支付方式
        $orderinfo = OrderModel::get(['order_sn' => $orderSn]);
        if (!$orderinfo) {
            $this->error('参数错误', '', 0, $this->serial_number);
        }
        if ($orderinfo->status != 1) {
            $this->error('订单已支付', '', 0, $this->serial_number);
        }
        $orderinfo->save(['pay_type' => $payType]);
//        if (!$this->auth->miniAppOpenId) {
//            $this->error('微信未授权','',0,$this->serial_number);
//        }
        //回调链接
        $notifyurl = $this->request->root(true) . '/api/order/notifyx/paytype/' . $payType;
        $returnurl = $this->request->root(true) . '/api/order/returnx/paytype/' . $payType . '/out_trade_no/' . $orderinfo->order_sn;
        $this->testNotifyx($orderinfo);
        $this->success('支付成功', '', 1, $this->serial_number);
//        $response = \addons\epay\library\Service::submitOrder($orderinfo->product_total_price, $orderinfo->order_sn, $payType, '商品订单', $notifyurl, $returnurl, 'miniapp', $this->auth->miniAppOpenId);
//        if ($response) {
//            $this->success('下单成功', ['response' => $response]);
//        } else {
//            $this->error('下单失败');
//        }
    }

    /** 测试回调 */
    public function testNotifyx($oderInfo)
    {
        $oderInfo->save(['status' => 2, 'pay_time' => datetime(time())]);
        //执行发货
//        $this->updStatus();
    }

    /**
     * 微信支付回调
     * @return void
     * @throws \Yansongda\Pay\Exceptions\InvalidArgumentException
     * @throws \Yansongda\Pay\Exceptions\InvalidConfigException
     * @throws \Yansongda\Pay\Exceptions\InvalidSignException
     */
    public function notifyx()
    {
        $paytype = $this->request->param('paytype');
        $pay     = Service::checkNotify($paytype);
        if (!$pay) {
            adlog('签名信息', '签名错误');
            echo '签名错误';
            return;
        }
        $data = $pay->verify();
        Db::startTrans();
        try {
            $out_trade_no = $data['out_trade_no'];
            $orderinfo    = OrderModel::where('order_sn', $out_trade_no)->find();
            $status       = 2;
            if ($orderinfo['type'] == 2) {
                $status = 3;
            }
            OrderModel::where('order_sn', $out_trade_no)->update(['status' => $status, 'pay_time' => time()]);
            //执行发货
//            $this->updStatus();
            Db::commit();
        } catch (PDOException $e) {
            Db::rollback();
            $this->error($e->getMessage());
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        echo $pay->success();
    }

    /**
     * 微信发货管理
     */
    public function updStatus($ids, $access_token)
    {
        $order = Db::name('orderpurchase')->where('id', $ids)->find();
        #日期格式
        $date_str     = date('Y-m-d H:i:s', \time());
        $date         = new \DateTime($date_str, new \DateTimeZone('Asia/Shanghai'));
        $iso8601_date = $date->format(\DateTime::ATOM);
        $data         = [
            'order_key'      => ['order_number_type' => 2, 'transaction_id' => $order['transaction_id']], #原支付交易对应的微信订单号
            'delivery_mode'  => 1,#发货模式
            'logistics_type' => 4,#发货方式
            'shipping_list'  => [['item_desc' => '订货商品']],#商品信息
            'upload_time'    => $iso8601_date,#日期格式
            'payer'          => ['openid' => $order['openid']] #openid
        ];
        $url          = 'https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=' . $access_token;
        $this->curl_post_https($url, json_encode($data, JSON_UNESCAPED_UNICODE));
        return true;
    }

    public function curl_post_https($url, $data, $header = [])
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_HEADER, $header);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }

    /** 订单列表 */
    public function list()
    {
        $param = $this->request->param();
        $this->validateCommon('Order.list', $this->serial_number);
        $where['user_id'] = $this->auth->id;
        if ($param['status'] == 1) $where['status'] = ['in', [1, 2, 3, 4, 5]];
        if ($param['status'] == 2) $where['status'] = ['in', [2]];
        if ($param['status'] == 3) $where['status'] = ['in', [5]];
        if ($param['status'] == 4) $where['status'] = ['in', [3]];
        if ($param['status'] == 5) $where['status'] = ['in', [4]];
        $field = "order_sn orderSn,product_name productName,product_image productImage"
                 . ",product_style productStyle,product_total_price productTotalPrice,product_num productNum"
                 . ",status orderStatus,product_id productId";
        $list  = OrderModel::where($where)
                           ->field($field)
                           ->order('create_time desc')
                           ->paginate($param['pageCount'], false, ['page' => $param['page']])
                           ->each(function ($item) {
                               $item['productDetail'] = Product::where('id', $item['productId'])->value('product_detail');
                               $item['productName']   = $item['productName'] . '-' . $item['productStyle'];
                               $item['productImage']  = getCurrentUrl() . $item['productImage'];
                               if ($item['orderStatus'] == 1) $item['orderStatusMemo'] = '待支付';
                               if ($item['orderStatus'] == 2) $item['orderStatusMemo'] = '已下单';
                               if ($item['orderStatus'] == 3) $item['orderStatusMemo'] = '已完成';
                               if ($item['orderStatus'] == 4) $item['orderStatusMemo'] = '已取消';
                               if ($item['orderStatus'] == 5) $item['orderStatusMemo'] = '已发货';
                           });
        $this->success('订单列表', $list, 1, $this->serial_number);
    }

    /** 订单详情 */
    public function orderDetail()
    {
        $param = $this->request->param();
        $this->validateCommon('Order.orderDetail', $this->serial_number);
        $orderInfo = OrderModel::get(['order_sn' => $param['orderSn']]);
        if (!$orderInfo) $this->error('订单编号错误', '', 0, $this->serial_number);
        $addressInfo      = json_decode($orderInfo->address_json, true);
        $photoAddressInfo = json_decode($orderInfo->user_address_json, true);
        $userSchoolInfo   = json_decode($orderInfo->user_school_json, true);
        $productDetail    = Product::where('id', $orderInfo->product_id)->value('product_detail');
        $weekarray        = array("日", "一", "二", "三", "四", "五", "六"); //先定义一个数组
        $week             = '星期' . $weekarray[date("w", strtotime($orderInfo->photo_time))];
        $newOrderInfo     = [
            'addressArr'       => $addressInfo,
            'photoAddressArr'  => $photoAddressInfo,
            'userSchoolArr'    => $userSchoolInfo,
            'productImage'     => getCurrentUrl() . $orderInfo->product_image,
            'productName'      => $orderInfo->product_name . '-' . $orderInfo->product_style,
            'productDetail'    => $productDetail,
            'productNum'       => $orderInfo->product_num,
            'photoPeopleNum'   => $orderInfo->photo_people_num,
            'photoTime'        => $orderInfo->photo_time . ' ' . $week,
            'memo'             => $orderInfo->memo,
            'orderSn'          => $orderInfo->order_sn,
            'orderStatus'      => $orderInfo->status,
            'orderPrice'       => $orderInfo->product_total_price,
            'createTime'       => $orderInfo->create_time,
            'sendTime'         => $orderInfo->accept_time ?? "",
            'acceptTime'       => $orderInfo->accept_time ?? "",
            'cancelTime'       => $orderInfo->cancel_time ?? "",
            'logisticsCompany' => $orderInfo->logistics_company ?? "",
            'logisticsNumber'  => $orderInfo->logistics_number ?? "",
        ];
        $this->success('订单详情', $newOrderInfo);
    }

    /** 取消订单 */
    public function cancelOrder()
    {
        $param = $this->request->param();
        $this->validateCommon('Order.cancelOrder', $this->serial_number);
        $orderInfo = OrderModel::get(['order_sn' => $param['orderSn']]);
        if (!$orderInfo) $this->error('订单编号错误', '', 0, $this->serial_number);
        if (in_array($orderInfo->status, [3, 4, 5])) $this->error('该状态不可取消', '', 0, $this->serial_number);
        $res = $orderInfo->save(['status' => 4, 'cancel_time' => datetime(time())]);
        if ($res) $this->success('取消成功', '', 1, $this->serial_number);
        $this->error('取消失败');
    }

    /** 支付清单 */
    public function waitOrderPay()
    {
        $param = $this->request->param();
        $this->validateCommon('Order.waitOrderPay', $this->serial_number);
        $field = "order_sn orderSn,product_name productName,product_image productImage"
                 . ",product_style productStyle,product_total_price productTotalPrice,product_num productNum"
                 . ",status orderStatus,product_id productId";
        $list  = OrderModel::where(['status' => 1, 'user_id' => $this->auth->id])
                           ->field($field)
                           ->paginate($param['pageCount'], false, ['page' => $param['page']])
                           ->each(function ($item) {
                               $item['residueTime'] = ($item['create_time'] + 900) - time();
                               if ($item['residueTime'] <= 0) $item['residueTime'] = 0;
                               $item['productName'] = $item['productName'] . '-' . $item['productStyle'];
                           });
        $this->success('支付清单', $list, 1, $this->serial_number);

    }
}